package gui;

import audio.WavWriter;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ChangeEvent;

/**
 * ViewPane is a three section panel with a toolbar on top, a line graph in the center and a bar graph on the bottom.
 * @author Peter Schilling, Jeff Hunter
 */
public class ViewPane extends JPanel {

	private GraphPanel bottomPanel;
	private JButton closeButton;
	private JSlider zoomSlider;
	private JToolBar controlToolbar;
	private JButton playButton;
	private JToggleButton recordToggleButton;
	private GraphPanel topPanel;
	private WavWriter wavWriter_;
	private boolean isRecording_ = false;
	private File tempFile_;


	public ViewPane(File tempFile) {
		tempFile_ = tempFile;
		tempFile_.delete();
		try {
			tempFile_.createNewFile();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		tempFile_.deleteOnExit();

		// gui init...
		GridBagConstraints gridBagConstraints;
		setLayout(new GridBagLayout());

		controlToolbar = new JToolBar();
		recordToggleButton = new JToggleButton();
		playButton = new JButton();
		closeButton = new JButton();
		zoomSlider = new JSlider();

		topPanel = new GraphPanel(false);
		bottomPanel = new GraphPanel(true);

		controlToolbar.setBorder(null);
		controlToolbar.setFloatable(false);
		controlToolbar.setRollover(true);

		recordToggleButton.setText("Record");
		recordToggleButton.setActionCommand("recordToggleButton");
		recordToggleButton.setFocusable(false);
		recordToggleButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				recordToggleButtonActionPerformed(evt);
			}
		});
		controlToolbar.add(recordToggleButton);
		controlToolbar.addSeparator();

		playButton.setText("Play");
		playButton.setFocusable(false);
		playButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				playButtonActionPerformed(evt);
			}
		});
		controlToolbar.add(playButton);
		controlToolbar.addSeparator();


		zoomSlider.setValue(1);
		zoomSlider.setMinimum(1);
		zoomSlider.setMaximum(100);

		zoomSlider.addChangeListener(new javax.swing.event.ChangeListener() {

			public void stateChanged(javax.swing.event.ChangeEvent evt) {
				zoomSliderStateChanged(evt);
			}
		});
		controlToolbar.add(zoomSlider);

		controlToolbar.addSeparator();

		closeButton.setText("Close");
		closeButton.setFocusable(false);
		closeButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				closeButtonActionPerformed(evt);
			}
		});
		controlToolbar.add(closeButton);

		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
		gridBagConstraints.weightx = 1.0;
		gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints.insets = new Insets(0, 5, 0, 5);
		add(controlToolbar, gridBagConstraints);

		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.ipady = 5;
		gridBagConstraints.weighty = 0.5;
		gridBagConstraints.insets = new Insets(5, 5, 5, 5);
		add(new JScrollPane(topPanel,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS),
				gridBagConstraints);

		gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.fill = GridBagConstraints.BOTH;
		gridBagConstraints.ipady = 5;
		gridBagConstraints.weighty = 0.5;
		gridBagConstraints.insets = new Insets(5, 5, 5, 5);
		add(bottomPanel, gridBagConstraints);

		wavWriter_ = new WavWriter(tempFile_, this);
		topPanel.addWavWriter(wavWriter_);
		bottomPanel.addWavWriter(wavWriter_);
	}


	/**
	 * starts or stops recording
	 * @param evt
	 */
	private void recordToggleButtonActionPerformed(ActionEvent evt) {
		if (!isRecording_)
			wavWriter_.startRecord();
		else
			wavWriter_.stopRecord();
		isRecording_ = !isRecording_;
	}

	/**
	 * Closes the currently focused tab
	 * @param evt
	 */
	private void closeButtonActionPerformed(ActionEvent evt) {
		MainFrame g = (MainFrame) this.getParent().getParent().getParent().getParent().getParent();
		g.removeTab(this);
	}

	/**
	 * Plays the the currently opened file
	 * @param evt
	 */
	private void playButtonActionPerformed(ActionEvent evt) {
		if (isRecording_)
			recordToggleButton.doClick();
		wavWriter_.playFile();
	}

	/**
	 * Updates the zoom when slider is changed
	 * @param evt
	 */
	private void zoomSliderStateChanged(ChangeEvent evt) {
		topPanel.setZoom(zoomSlider.getValue());
	}

	/**
	 * cuts graph points
	 * @return copied data
	 */
	public byte[] cut() {
		return topPanel.cut();
	}

	/**
	 * copies graph points
	 * @return copied data
	 */
	public byte[] copy() {
		return topPanel.copy();
	}

	/**
	 * pastes graph points
	 * @param pointsToAdd
	 */
	public void paste(byte[] pointsToAdd) {
		topPanel.paste(pointsToAdd);
	}

	/**
	 * deletes graph points
	 */
	public void delete() {
		topPanel.delete();
	}
	
	public void fourier() {
		topPanel.fourier();
	}
	
	public void setSampleRate(float sr){
		wavWriter_.setSampleRate(sr);
		topPanel.repaint();
		bottomPanel.repaint();
	}

	public GraphPanel getTopGraph() {
		return topPanel;
	}

	public GraphPanel getBottomGraph() {
		return bottomPanel;
	}

	/**
	 * 
	 * @return gets all points
	 */
	public double[] getPoints() {
		return topPanel.getPoints();
	}

	public void deleteAll() {
		topPanel.deleteAll();
	}

	public void setNumBins(int numBins) {
		wavWriter_.setNumBins(numBins);
	}

	public void filterSelection() {
		wavWriter_.newFilter(bottomPanel.getStartSelection(), bottomPanel.getEndSelection(), bottomPanel.getWidth());
	}

	public void loadFile(File f) {
		FileInputStream openedFile = null;
		FileOutputStream currentFile = null;
		try {
			openedFile = new FileInputStream(f);
			currentFile = new FileOutputStream(tempFile_);
			byte[] buffer = new byte[4096];
			int bytesRead;

			while ((bytesRead = openedFile.read(buffer)) != -1)
				currentFile.write(buffer, 0, bytesRead); // write
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (openedFile != null)
				try {
					openedFile.close();
				} catch (IOException e) {
				}
			if (currentFile != null)
				try {
					currentFile.close();
				} catch (IOException e) {
				}
		}
		wavWriter_.graphAudio();
	}

	public void saveFile(File savedFile) {
		FileInputStream openedFile = null;
		FileOutputStream currentFile = null;

		try {
			openedFile = new FileInputStream(tempFile_);
			currentFile = new FileOutputStream(savedFile);
			byte[] buffer = new byte[4096];
			int bytesRead;

			while ((bytesRead = openedFile.read(buffer)) != -1)
				currentFile.write(buffer, 0, bytesRead); // write
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (openedFile != null)
				try {
					openedFile.close();
				} catch (IOException e) {
				}
			if (currentFile != null)
				try {
					currentFile.close();
				} catch (IOException e) {
				}
		}
	}
	
	public void setWindowMode(int windowMode) {
		wavWriter_.setWindowMode(windowMode);
	}
}
